package app.controller;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.dj.common.response.ApiResponse;
import com.dj.gateway.app.authorization.manager.WebfluxReactiveAuthorizationManager;
import com.dj.gateway.app.constant.HeaderConstants;
import com.dj.gateway.app.utils.RedisUtil;
import com.dj.gateway.app.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;

import java.util.concurrent.TimeUnit;

/**
 * @description: 智能客服在线聊天c端用户登录用原token换临时token
 * @author: sj
 * @time: 2021/9/17 21:27 下午
 */
@RestController
@Slf4j
public class ChatBotTokenController {
    final String TOKEN_PREFIX = "auth:";

    @Autowired
    private RedisUtil redisUtil;

    @GetMapping("/getChatBotToken")
    public ApiResponse chatBotToken(ServerWebExchange exchange) {

        String newToken;
        try {
//            log.info("开始生成智能客服二次token");
            String token = getAccessToken(exchange.getRequest());
            if (StrUtil.isBlank(token)) {
                return ApiResponse.fail(HttpStatus.UNAUTHORIZED.value(), "cookies中 access_token为空");
            }

            String tokenInfo = redisUtil.get(TOKEN_PREFIX + token);
            if (StrUtil.isBlank(tokenInfo)) {
                log.error("用户token已失效：{}", token);
                return ApiResponse.fail(HttpStatus.UNAUTHORIZED.value(), "token失效");
            }

            newToken = RandomUtil.randomString(20);
            redisUtil.setEx(HeaderConstants.ARTIFICIAL_CHAT_TOKEN + newToken, tokenInfo, 30, TimeUnit.MINUTES);

        } catch (Exception e) {
            return ApiResponse.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), ExceptionUtil.getMessage(e));
        }

        return ApiResponse.success(newToken);
    }


    private String getAccessToken(ServerHttpRequest request) {
        String accessToken = "";

        MultiValueMap<String, HttpCookie> cookies = request.getCookies();
        HttpCookie accessTokenCookie = cookies.getFirst("access_token");
        if(getAnotherAccessTokenFlag(WebfluxReactiveAuthorizationManager.ANOTHER_ACCESS_TOKEN_FLAG)){
            accessTokenCookie = cookies.getFirst("another_access_token");
        }
        if (accessTokenCookie != null) {
            accessToken = accessTokenCookie.getValue();
        }

        if (StringUtils.isBlank(accessToken)) {
            accessToken = request.getHeaders().getFirst("access_token");
        }

        if (StringUtils.isBlank(accessToken)) {
            accessToken = request.getQueryParams().getFirst("access_token");
        }
        if (StringUtils.isBlank(accessToken)) {
            accessTokenCookie = cookies.getFirst("access_token");
            if(accessTokenCookie!=null){
                accessToken = accessTokenCookie.getValue();
                log.info("cookie获取access_token详情:{}",accessToken);
            }
        }
        return accessToken;
    }

    private Boolean getAnotherAccessTokenFlag(String key){
        boolean result = false;
        try {
            RedisUtil redisUtil = SpringUtils.getApplicationContext().getBean("redisUtil", RedisUtil.class);
            String value = redisUtil.get(WebfluxReactiveAuthorizationManager.ANOTHER_ACCESS_TOKEN_FLAG);
            String configValue = JSONObject.parseObject(value).getString("configValue");
            result = Boolean.parseBoolean(configValue);
        }catch (Exception e){
            log.error("redis缓存布尔类型转换出错!",e);
        }
        return result;
    }

}
